package com.pig4cloud.pig.module.service.wx.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.common.core.exception.TransactionalException;
import com.pig4cloud.pig.common.core.util.MathUtil;
import com.pig4cloud.pig.common.core.util.OrderUtil;
import com.pig4cloud.pig.common.core.wx.WxAppPay;
import com.pig4cloud.pig.module.api.entity.splitAccount.SplitAccount;
import com.pig4cloud.pig.module.api.entity.splitAccount.SplitAccountRecord;
import com.pig4cloud.pig.module.api.entity.wx.WxPayTransaction;
import com.pig4cloud.pig.module.api.entity.wx.WxUser;
import com.pig4cloud.pig.module.api.entity.wx.WxUserCashRecord;
import com.pig4cloud.pig.module.mapper.splitAccount.SplitAccountMapper;
import com.pig4cloud.pig.module.mapper.splitAccount.SplitAccountRecordMapper;
import com.pig4cloud.pig.module.mapper.wx.WxUserCashRecordMapper;
import com.pig4cloud.pig.module.mapper.wx.WxUserMapper;
import com.pig4cloud.pig.module.service.splitAccount.ISplitAccountService;
import com.pig4cloud.pig.module.service.wx.IWxPayTransactionService;
import com.pig4cloud.pig.module.service.wx.IWxTemplateService;
import com.pig4cloud.pig.module.service.wx.IWxUserCashRecordService;
import com.pig4cloud.pig.module.service.wx.IWxUserService;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class WxUserCashRecordServiceImpl extends ServiceImpl<WxUserCashRecordMapper, WxUserCashRecord> implements IWxUserCashRecordService {

    @Resource
    private WxUserCashRecordMapper cashRecordMapper;
    @Resource
    private SplitAccountRecordMapper splitAccountRecordMapper;
    @Resource
    private SplitAccountMapper splitAccountMapper;
    @Resource
    private ISplitAccountService splitAccountService;
    @Resource
    private IWxTemplateService wxTemplateService;
    @Resource
    private IWxUserService wxUserService;
	@Resource
	private WxUserMapper wxUserMapper;
	@Resource
	private IWxPayTransactionService payTransactionService;


    @Value("${web.appid}")
    private String appid;
    @Value("${web.appidMp}")
    private String appidMp;
    @Value("${web.secret}")
    private String secret;
    @Value("${web.mch_id}")
    private String mch_id;
    @Value("${web.api_key}")
    private String api_key;
    @Value("${web.keyPath}")
    private String keyPath;//微信支付的回调地址


    @Override
    @Transactional
    public Map<String,Object> addRecord(WxUser user, double payMoney, SplitAccount splitAccount) {
        Map<String,Object> map = new HashMap<>();
        int ret = 0;
        try{
            String tradeNo = OrderUtil.getPayNo();
            WxUserCashRecord cashRecord = new WxUserCashRecord();
            cashRecord.setTradeNo(tradeNo);
            cashRecord.setCreateTime(new Date());
            cashRecord.setUserId(user.getId());
            cashRecord.setWxOpenId(user.getOpenId());
            cashRecord.setPayMoney(new BigDecimal(payMoney));
            cashRecord.setMchId(mch_id);
            cashRecord.setMchAppid(appid);
            cashRecord.setRemark("提现到零钱");
            cashRecord.setPayState(0);
            cashRecord.setPayTime(new Date());
            ret = cashRecordMapper.insert(cashRecord);
            if(ret <= 0){
                throw new TransactionalException("cashRecordMapper insert error");
            }

            map.put("result_code","FAILE");
            map.put("err_code_des","请求失败");
            int status = 0;
            WxAppPay wxAppPay = new WxAppPay("", secret, appid, mch_id,api_key);
            Map<String, String> retRequest = wxAppPay.weixinChangePay(cashRecord.getTradeNo(),cashRecord.getPayMoney(),cashRecord.getWxOpenId(),keyPath,"用户主动提现");
            if(retRequest.containsKey("return_code")){
                String return_code = retRequest.get("return_code");
                String result_code = retRequest.get("result_code");
                String err_code_des = retRequest.containsKey("err_code_des") ? retRequest.get("err_code_des") : "";
                map.put("result_code",result_code);
                map.put("err_code_des",err_code_des);
                cashRecord.setResultCode(result_code);
                if(result_code.equals("SUCCESS")){
                    cashRecord.setPayState(1);//支付成功
                    status = 1;


					// 添加 微信支付的 动账记录
					WxPayTransaction transaction = new WxPayTransaction();
					transaction.setPayType(0);// 0 -微信支付
					transaction.setTransactionId(cashRecord.getTradeNo());
					transaction.setUserId(user.getId());
					transaction.setFeeType("user_tixian");
					transaction.setTotalMoney(cashRecord.getPayMoney());
					if(StrUtil.isNotEmpty(user.getNickName())){
						transaction.setNickName(EmojiParser.parseToAliases(user.getNickName()));
					}
					transaction.setCreateTime(new Date());
					transaction.setInOrOut(0);//动账  0 - 出账 1 - 进账
					transaction.setRemark("用户提现到零钱");
					payTransactionService.save(transaction);


                }else{
                    cashRecord.setPayState(2);//支付失败
                    cashRecord.setErrCodeDes(err_code_des);
                }
                String pay_str = retRequest.get("pay_str");
                String reback_str = retRequest.get("reback_str");
                cashRecord.setPayStr(pay_str);
                cashRecord.setRebackStr(reback_str);
            }

            ret = cashRecordMapper.updateById(cashRecord);
            if(ret <= 0){
                throw new TransactionalException("cashRecordMapper updateById error");
            }

            if(status == 1){
                double totalAmount = splitAccount.getSplitMoney().doubleValue();
                totalAmount = MathUtil.getDouble(totalAmount - payMoney);
                splitAccount.setSplitMoney(new BigDecimal(totalAmount));
                ret = splitAccountMapper.updateById(splitAccount);
                if(ret <= 0){
                    throw new TransactionalException("splitAccountRecordMapper insert error");
                }

                SplitAccountRecord splitAccountRecord = new SplitAccountRecord();
                splitAccountRecord.setUserId(user.getId());
                splitAccountRecord.setAccountId(splitAccount.getId());
                splitAccountRecord.setCreateTime(new Date());
                //动账类型  0 - 提现 1 - 重置  2 - 分成增加
                splitAccountRecord.setFromType(0);
                //1 - 进账  0 - 出账
                splitAccountRecord.setInOrOut(0);
                splitAccountRecord.setRemark("用户发起提现");
                splitAccountRecord.setSplitMoney(new BigDecimal(payMoney));
                ret = splitAccountRecordMapper.insert(splitAccountRecord);
                if(ret <= 0){
                    throw new TransactionalException("splitAccountRecordMapper insert error");
                }
            }

            map.put("ret",ret);

            return map;
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("splitAccountRecordMapper insert error");
        }
    }

	@Override
	@Transactional
	public Map<String, Object> checkRecord(WxUserCashRecord cashRecord) {
		Map<String,Object> map = new HashMap<>();
		int ret = 0;
		try{
			//账户类型  0 - 平台   1 - 物业  2 -  小区  3 - 商家   4 - 个人
			SplitAccount splitAccount = splitAccountMapper.selectById(cashRecord.getAccountId());
			map.put("result_code","FAILE");
			map.put("err_code_des","请求失败");
			int status = 0;
			WxAppPay wxAppPay = new WxAppPay("", secret, appid, mch_id,api_key);
			Map<String, String> retRequest = wxAppPay.weixinChangePay(cashRecord.getTradeNo(),cashRecord.getPayMoney(),cashRecord.getWxOpenId(),keyPath,"用户主动提现");
			if(retRequest.containsKey("return_code")){
				String result_code = retRequest.get("result_code");
				String err_code_des = retRequest.containsKey("err_code_des") ? retRequest.get("err_code_des") : "";
				map.put("result_code",result_code);
				map.put("err_code_des",err_code_des);
				cashRecord.setResultCode(result_code);
				if(result_code.equals("SUCCESS")){
					cashRecord.setPayState(1);//支付成功
                    cashRecord.setPayTime(new Date());
                    map.put("err_code_des","提现成功");
					status = 1;

					WxUser user  = wxUserService.findById(cashRecord.getUserId());

					// 添加 微信支付的 动账记录
					WxPayTransaction transaction = new WxPayTransaction();
					transaction.setPayType(0);// 0 -微信支付
					transaction.setTransactionId(cashRecord.getTradeNo());
					transaction.setUserId(user.getId());
					transaction.setFeeType("user_tixian");
					transaction.setTotalMoney(cashRecord.getPayMoney());
					if(StrUtil.isNotEmpty(user.getNickName())){
						transaction.setNickName(EmojiParser.parseToAliases(user.getNickName()));
					}
					transaction.setCreateTime(new Date());
					transaction.setInOrOut(0);//动账  0 - 出账 1 - 进账
					transaction.setRemark("用户提现到零钱");
					payTransactionService.save(transaction);


				}else{
					cashRecord.setPayState(2);//支付失败
					cashRecord.setErrCodeDes(err_code_des);

                    double totalAmount = splitAccount.getSplitMoney().doubleValue();
                    totalAmount = MathUtil.getDouble(totalAmount + cashRecord.getRegPayMoney().doubleValue());
                    splitAccount.setSplitMoney(new BigDecimal(totalAmount));

                    double freezenMoney = splitAccount.getFreezen().doubleValue();
                    freezenMoney = MathUtil.getDouble(freezenMoney - cashRecord.getRegPayMoney().doubleValue());
                    splitAccount.setFreezen(new BigDecimal(freezenMoney));
				}
				String pay_str = retRequest.get("pay_str");
				String reback_str = retRequest.get("reback_str");
				cashRecord.setPayStr(pay_str);
				cashRecord.setRebackStr(reback_str);
			}

			ret = cashRecordMapper.updateById(cashRecord);
			if(ret <= 0){
				throw new TransactionalException("cashRecordMapper updateById error");
			}

			if(status == 1){
			    //冻结金额 减掉 当前提现的金额
				double freezenMoney = splitAccount.getFreezen().doubleValue();
                freezenMoney = MathUtil.getDouble(freezenMoney - cashRecord.getPayMoney().doubleValue());
				splitAccount.setFreezen(new BigDecimal(freezenMoney));

				ret = splitAccountMapper.updateById(splitAccount);
				if(ret <= 0){
					throw new TransactionalException("splitAccountRecordMapper insert error");
				}

				WxUser wxUser = wxUserService.findById(cashRecord.getUserId());
				if(wxUser != null){
					double integralFreez = wxUser.getIntegralFreez();
					integralFreez = integralFreez - cashRecord.getPayMoney().doubleValue();
					wxUser.setIntegralFreez(integralFreez);
					ret = wxUserMapper.updateById(wxUser);
					if(ret <= 0){
						throw new TransactionalException("userMapper updateById error");
					}
				}


				boolean bl = true;
                QueryWrapper<SplitAccountRecord> qw = new QueryWrapper<>();
				qw.eq("cash_record_id",cashRecord.getId());
				qw.orderByDesc("create_time");
				qw.last("limit 1");
				SplitAccountRecord splitAccountRecord = splitAccountRecordMapper.selectOne(qw);
				if(splitAccountRecord == null){
                    splitAccountRecord = new SplitAccountRecord();
                    bl = false;
                }

                splitAccountRecord.setUserId(cashRecord.getUserId());
                splitAccountRecord.setAccountId(splitAccount.getId());
                splitAccountRecord.setCreateTime(new Date());
                //动账类型  0 - 提现 1 - 重置  2 - 分成增加
                splitAccountRecord.setFromType(0);
                //1 - 进账  0 - 出账
                splitAccountRecord.setInOrOut(0);
                splitAccountRecord.setRemark("用户发起提现");
                splitAccountRecord.setSplitMoney(cashRecord.getPayMoney());
                splitAccountRecord.setCashState(cashRecord.getCheckState());
                splitAccountRecord.setCashRemark(cashRecord.getCheckResult());
                if(!bl){//不存在 新添加一个
                    ret = splitAccountRecordMapper.insert(splitAccountRecord);
                }else{
                    ret = splitAccountRecordMapper.updateById(splitAccountRecord);
                }
                if(ret <= 0){
                    throw new TransactionalException("splitAccountRecordMapper insert error");
                }
                wxTemplateService.sendWxMsgTiXian(wxUser,cashRecord,splitAccount.getSplitMoney().doubleValue());
			}
			map.put("ret",ret);
			return map;
		}catch (Exception e){
			e.printStackTrace();
			throw new TransactionalException("splitAccountRecordMapper insert error");
		}
	}

	@Override
	public WxUserCashRecord getRecordByOrderId(int merId, long orderId,long orderInfoId) {
    	QueryWrapper<WxUserCashRecord> qw = new QueryWrapper<>();
    	qw.eq("mer_id",merId);
    	qw.eq("order_id",orderId);
		qw.eq("order_info_id",orderInfoId);
		qw.last("limit 1");
		return cashRecordMapper.selectOne(qw);
	}
}
